package com.ynding;

import java.applet.Applet;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.net.URL;

/**
 * <p> 电子相册 </p>
 *
 * @author ynding
 * @version 2021/4/14
 **/
public class PhotoAlbum extends Applet {
    //Applet组件
    private Panel buttonPanel = new Panel(); //默认值为FlowLayout
    private Panel picturePanel = new Panel(); //默认值为FlowLayout
    private PhotoCanvas canvas = new PhotoCanvas(); //图像浏览器
    private Button bck = new Button("上一副图"); //显示上一副图的按钮
    private Button fwd = new Button("下一幅图"); //显示下一副图的按钮
    private Button fit = new Button("调整图片大小"); //调整图像大小的按钮
    private Label showing = new Label("正在显示："); //表示显示状态的标签
    private TextField txt = new TextField("无", 10); //表示状态的文字
    //其他变量
    private Image[] photos;
    private String[] imageNames;
    private URL url;
    private int currIdx = -1;
    //由html文档初始化的变量
    private String numPhotosString;
    private int num_photos;
    private String image_loc;

    //获取小应用程序的相关信息
    @Override
    public String getAppletInfo() {
        return new String("by Ali, version 1.0, Copyright (c) 2003.");
    }

    //初始化，当浏览器创建一个Applet时该方法将被调用
    @Override
    public void init() {
        //为避免错误，这一行必须最先被运行
        loadParameters();//调用自定义的方法
        photos = new Image[num_photos];
        //添加所有的GUI组件
        setLayout(new BorderLayout(2, 2));
        add(picturePanel, BorderLayout.CENTER);
        add(buttonPanel, BorderLayout.SOUTH);
        canvas.setSize(getSize());
        canvas.setBackground(Color.white);
        picturePanel.add(canvas);
        buttonPanel.add(bck);
        buttonPanel.add(fwd);
        buttonPanel.add(showing);
        showing.setBackground(Color.lightGray);
        buttonPanel.add(txt);
        buttonPanel.add(fit);
        txt.setBackground(Color.lightGray);
        txt.setEditable(false);
        setBackground(Color.lightGray); //小应用程序的颜色
        //为按钮添加鼠标事件侦测器
        bck.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                showPreviousImage();
            }
        });
        fwd.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                showNextImage();
            }
        });
        fit.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                fitImage();
            }
        });
        //作为欢迎信息显示在屏幕上
        canvas.setText("请单击[下一副图]按钮，开始浏览图片");
    }

    //当浏览器启动Applet或者小应用程序初始化完毕之后，该方法将被调用
    @Override
    public void start() {
        //使画布完全占满空白区域
        canvas.setSize(picturePanel.getSize());
    }

    //当浏览器失去焦点时，该方法将被调用
    @Override
    public void stop() {
    }

    //当Applet被刷新或者当用户关闭浏览器时，该方法将被调用
    @Override
    public void destroy() {
    }

    //这是Applet实现在屏幕上输出的方法，可以实现按钮、文字、图像等等，
    //在本实例中，PhotoCanvas类被用来作为显示图像的画布组件。
    @Override
    public void paint(Graphics g) {
    }

    //该方法从html文档中获得信息，允许用户设置小应用程序的某些行为。
    //NUM_PHOTOS 指本实例中所要显示的图像数量.
    //IMAGE_LOC 存放本实例所要图片的文件夹路径.
    //IMAGEx 是一个用来按照名称上载每张图片的驻足点，x的值从1到NUM_PHOTOS
    private void loadParameters() {
        String param;
        //获得图片数量
        num_photos = 1;
        numPhotosString = getParameter("NUM_PHOTOS");
        if (numPhotosString != null) {
            try {
                num_photos = Integer.parseInt(numPhotosString);
            } catch (Exception e) {
                //默认值为1
            }
        }
        //获取包含图片的文件夹名称
        image_loc = getParameter("IMAGE_LOC");
        if (image_loc == null) {
            image_loc = ".";
        }
        //默认值是小应用程序所在的文件夹
        //初始化用来存放图片的数组
        imageNames = new String[num_photos];
        //循环，获取所有的图片名称
        for (int i = 0; i < num_photos; i++) {
            param = new String("IMAGE" + String.valueOf(i + 1));
            imageNames[i] = new String(getParameter(param));
        }
    }

    //递减图片索引
    public void showPreviousImage() {
        currIdx--;
        if (currIdx < 0) {
            currIdx = num_photos - 1;
        }
        displayPhoto(currIdx);
    }

    //递增图片索引
    public void showNextImage() {
        currIdx++;
        if (currIdx == num_photos) {
            currIdx = 0;
        }
        displayPhoto(currIdx);
    }

    //上载图片，并且显示
    private void displayPhoto(int idx) {
        String path = "getImage not called";
        String text = "";
        try {
            //将图片存放到内存中
            if (photos[idx] == null) {
                canvas.setText("正在载入图片，请稍后...");
                path = image_loc + "/" + imageNames[idx];
                photos[idx] = getImage(getCodeBase(), path);
            }
            //更新PhotoCanvas.
            canvas.setImage(photos[idx]);
            //更新显示文字
            text = new String("第" + (idx + 1) + "幅，共" + num_photos + "幅");
            txt.setText(text);
        } catch (Exception e) {
            //只有对AppletViewer.exe起作用
            e.printStackTrace();
        }
    }

    //该方法计算图像大小、估计比例，并且与PhotoCanvas做比较，
    //然后对图像进行拉伸或挤压，使其恰好能放在给定的显示区域中。
    public void fitImage() {
        float imgH = 1, imgW = 1, scrH = 1, scrW = 1;
        float imgRat = 1, scrRat = 1;
        float multiplier = 1;
        int width = 100, height = 100;
        Image tempImage;
        //如果图片已经准备好，才执行下面的语句
        if (currIdx >= 0 && photos[currIdx] != null) {
            scrH = canvas.getSize().height;
            scrW = canvas.getSize().width;
            imgH = photos[currIdx].getHeight(canvas);
            imgW = photos[currIdx].getWidth(canvas);
            imgRat = imgW / imgH;
            scrRat = scrW / scrH;
            //调整高度
            if (imgRat <= scrRat) {
                multiplier = scrH / imgH;
            } else {
                //调整宽度
                multiplier = scrW / imgW;
            }
            width = (int) (imgW * multiplier);
            height = (int) (imgH * multiplier);
            //调整后生成图片
            tempImage = photos[currIdx].getScaledInstance(
                    width, height, Image.SCALE_SMOOTH);
            //显示调整后的图片
            canvas.setImage(tempImage);
            //更换数组中的旧图片
            if (width != imgW) {
                photos[currIdx] = tempImage;
            }
        }
    }
}

//PhotoCavas类，调用setter方法
class PhotoCanvas extends Canvas {
    private String text;
    private Image image;

    //构造函数，用来初始化私有变量
    public PhotoCanvas() {
        text = new String();
    }

    //显示文字，将图片设置为null
    public void setText(String text) {
        this.text = text;
        image = null;
        repaint();
    }

    //显示图片，将文字设置为空
    public void setImage(Image img) {
        image = img;
        text = "";
        repaint();
    }

    //覆盖paint方法
    @Override
    public void paint(Graphics g) {
        if (text.length() > 0) {
            //显示必要的文字
            g.drawString(text, 20, 20);
        }
        if (image != null) {
            //将图片保留在画布上
            g.drawImage(image, 0, 0, this);
        }
    }
}
